<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>线程池: C 线程池库</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">线程池<span id="projectnumber">&#160;1.0.0</span>
   </div>
   <div id="projectbrief">多线程并发工具</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- 制作者 Doxygen 1.9.8 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','搜索');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">载入中...</div>
<div class="SRStatus" id="Searching">搜索中...</div>
<div class="SRStatus" id="NoMatches">未找到</div>
</div>
</div>
</div>
</div>

<div><div class="header">
  <div class="headertitle"><div class="title">C 线程池库 </div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p><a class="anchor" id="md__r_e_a_d_m_e"></a> [<img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License" style="pointer-events: none;" class="inline"/>](LICENSE) <img src="https://img.shields.io/badge/C99-Standard-green.svg" alt="Standard" style="pointer-events: none;" class="inline"/> <img src="https://img.shields.io/badge/Platform-Linux-lightgrey.svg" alt="Platform" style="pointer-events: none;" class="inline"/> <img src="https://img.shields.io/badge/Build-CMake-brightgreen.svg" alt="Build" style="pointer-events: none;" class="inline"/></p>
<p>一个使用 POSIX 线程（pthreads）实现的、功能完整且线程安全的 C 语言线程池库。采用 CMake 构建系统，提供静态库和测试程序。</p>
<h1><a class="anchor" id="autotoc_md1"></a>
项目结构</h1>
<div class="fragment"><div class="line">.</div>
<div class="line">├── CMakeLists.txt              # CMake 构建配置文件</div>
<div class="line">├── bin/                        # 可执行文件输出目录</div>
<div class="line">│   └── threads_pool_test       # 测试程序</div>
<div class="line">├── build/                      # CMake 构建目录（生成的文件）</div>
<div class="line">├── docs/                       # 文档目录</div>
<div class="line">├── inc/                        # 头文件目录</div>
<div class="line">│   └── threads_pool.h          # 线程池头文件</div>
<div class="line">├── lib/                        # 库文件输出目录</div>
<div class="line">│   ├── libthreads_pool.a       # 静态库文件</div>
<div class="line">│   └── src/                    # 库源码目录</div>
<div class="line">│       └── threads_pool.c      # 线程池实现文件</div>
<div class="line">├── src/                        # 主程序源码目录（可选）</div>
<div class="line">└── test/                       # 测试代码目录</div>
<div class="line">    └── threads_pool_test.c     # 测试程序源码</div>
</div><!-- fragment --><h1><a class="anchor" id="autotoc_md2"></a>
功能特性</h1>
<ul>
<li><b>动态线程管理</b>: 可在运行时动态增加或减少工作线程的数量。</li>
<li><b>任务队列</b>: 使用双向链表管理任务队列，支持异步添加和执行任务。</li>
<li><b>线程安全</b>: 通过互斥锁 (<code>pthread_mutex_t</code>) 和条件变量 (<code>pthread_cond_t</code>) 确保所有操作线程安全。</li>
<li><b>任务取消</b>: 支持从队列中移除尚未执行的指定任务。</li>
<li><b>优雅关闭</b>: 提供安全的销毁机制，会等待所有已开始的任务完成，并清理所有资源。</li>
<li><b>可配置限制</b>: 可设置最大线程数和最大任务队列长度，防止资源过载。</li>
<li><b>资源清理</b>: 使用 <code>pthread_cleanup</code> 机制，确保在线程取消时也能正确释放锁，避免死锁。</li>
<li><b>CMake 构建</b>: 支持跨平台构建，生成静态库和测试程序。</li>
</ul>
<h1><a class="anchor" id="autotoc_md3"></a>
构建指南</h1>
<ol type="1">
<li>克隆或下载项目代码。</li>
<li>确保系统已安装 CMake 和 build-essential（GCC 编译工具链）。 <div class="fragment"><div class="line">sudo apt-get install cmake build-essential</div>
</div><!-- fragment --></li>
<li>创建并进入构建目录： <div class="fragment"><div class="line">mkdir build &amp;&amp; cd build</div>
</div><!-- fragment --></li>
<li>运行 CMake 配置项目： <div class="fragment"><div class="line">cmake ..</div>
</div><!-- fragment --></li>
<li>编译项目： <div class="fragment"><div class="line">make</div>
</div><!-- fragment --></li>
<li>运行测试程序（可选）： <div class="fragment"><div class="line">./bin/threads_pool_test</div>
</div><!-- fragment --></li>
</ol>
<p>编译完成后，静态库文件 <code>libthreads_pool.a</code> 将生成在 <code>lib/</code> 目录，测试程序 <code>threads_pool_test</code> 将生成在 <code>bin/</code> 目录。</p>
<h1><a class="anchor" id="autotoc_md4"></a>
在其他项目中使用</h1>
<h2><a class="anchor" id="autotoc_md5"></a>
方法 1：直接包含源码</h2>
<p>将 <code><a class="el" href="threads__pool_8h.html" title="线程池模块头文件">inc/threads_pool.h</a></code> 和 <code><a class="el" href="threads__pool_8c.html" title="线程池模块实现文件">lib/src/threads_pool.c</a></code> 复制到您的项目中，在编译时链接 <code>pthread</code> 库。</p>
<div class="fragment"><div class="line">gcc -std=c99 -pthread your_app.c threads_pool.c -o your_app</div>
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md6"></a>
方法 2：使用静态库</h2>
<ol type="1">
<li>将 <code><a class="el" href="threads__pool_8h.html" title="线程池模块头文件">inc/threads_pool.h</a></code> 复制到您的项目的头文件目录。</li>
<li>将 <code>lib/libthreads_pool.a</code> 复制到您的项目的库目录。</li>
<li>在编译时链接静态库和 <code>pthread</code> 库。</li>
</ol>
<div class="fragment"><div class="line">gcc -std=c99 -pthread -I/path/to/headers your_app.c -L/path/to/libs -lthreads_pool -o your_app</div>
</div><!-- fragment --><h1><a class="anchor" id="autotoc_md7"></a>
核心 API</h1>
<h2><a class="anchor" id="autotoc_md8"></a>
数据结构</h2>
<ul>
<li><code>ThreadsPoolMsg_st</code>: 线程池主结构体</li>
<li><code>TaskMsg_st</code>: 任务结构体</li>
<li><code>ThreadMsg_st</code>: 线程信息结构体</li>
</ul>
<h2><a class="anchor" id="autotoc_md9"></a>
主要函数</h2>
<div class="fragment"><div class="line"><a class="code hl_struct" href="structthreads_pool_msg.html">ThreadsPoolMsg_st_pt</a> <a class="code hl_function" href="threads__pool_8h.html#a871605529dee3dac1537de63589ab108">getNewThreadsPoolMsg</a>(<span class="keywordtype">int</span> orgActiveThreadsCot, <span class="keywordtype">int</span> maxWaitingTasksCot, <span class="keywordtype">int</span> maxActiveThreadsCot)</div>
<div class="ttc" id="astructthreads_pool_msg_html"><div class="ttname"><a href="structthreads_pool_msg.html">threadsPoolMsg</a></div><div class="ttdoc">线程池信息结构体</div><div class="ttdef"><b>Definition</b> <a href="threads__pool_8h_source.html#l00057">threads_pool.h:59</a></div></div>
<div class="ttc" id="athreads__pool_8h_html_a871605529dee3dac1537de63589ab108"><div class="ttname"><a href="threads__pool_8h.html#a871605529dee3dac1537de63589ab108">getNewThreadsPoolMsg</a></div><div class="ttdeci">ThreadsPoolMsg_st_pt getNewThreadsPoolMsg(int orgActiveThreadsCot, int maxWaitingTasksCot, int maxActiveThreadsCot)</div><div class="ttdoc">创建新的线程池</div><div class="ttdef"><b>Definition</b> <a href="threads__pool_8c_source.html#l00366">threads_pool.c:366</a></div></div>
</div><!-- fragment --><p> 创建并初始化一个新的线程池。</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> <a class="code hl_function" href="threads__pool_8h.html#a3ceec63a2e1c63606f561486b0b24e72">addNewTask</a>(<a class="code hl_struct" href="structthreads_pool_msg.html">ThreadsPoolMsg_st_pt</a> trdsPolMsgStPt, <span class="keywordtype">void</span>* (* handleFuncPt)(<span class="keywordtype">void</span>* arg), <span class="keywordtype">void</span>* handleFuncArg)</div>
<div class="ttc" id="athreads__pool_8h_html_a3ceec63a2e1c63606f561486b0b24e72"><div class="ttname"><a href="threads__pool_8h.html#a3ceec63a2e1c63606f561486b0b24e72">addNewTask</a></div><div class="ttdeci">int addNewTask(ThreadsPoolMsg_st_pt trdsPolMsgStPt, void *(*handleFuncPt)(void *arg), void *handleFuncArg)</div><div class="ttdoc">添加新任务到线程池</div><div class="ttdef"><b>Definition</b> <a href="threads__pool_8c_source.html#l00396">threads_pool.c:396</a></div></div>
</div><!-- fragment --><p> 向线程池中添加一个新任务。</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> <a class="code hl_function" href="threads__pool_8h.html#a7ebefc9eea4454da73914b2e62c3ef54">reduceTask</a>(<a class="code hl_struct" href="structthreads_pool_msg.html">ThreadsPoolMsg_st_pt</a> trdsPolMsgStPt, <span class="keywordtype">void</span>* (* destHandleFuncPt)(<span class="keywordtype">void</span>* arg))</div>
<div class="ttc" id="athreads__pool_8h_html_a7ebefc9eea4454da73914b2e62c3ef54"><div class="ttname"><a href="threads__pool_8h.html#a7ebefc9eea4454da73914b2e62c3ef54">reduceTask</a></div><div class="ttdeci">int reduceTask(ThreadsPoolMsg_st_pt trdsPolMsgStPt, void *(*destHandleFuncPt)(void *arg))</div><div class="ttdoc">从线程池中移除指定任务</div><div class="ttdef"><b>Definition</b> <a href="threads__pool_8c_source.html#l00431">threads_pool.c:431</a></div></div>
</div><!-- fragment --><p> 从队列中移除一个尚未执行的任务。</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> <a class="code hl_function" href="threads__pool_8h.html#a3c97656e7bb9d4709eca4ed29abf9d9c">addThread</a>(<a class="code hl_struct" href="structthreads_pool_msg.html">ThreadsPoolMsg_st_pt</a> trdsPolMsgStPt)</div>
<div class="ttc" id="athreads__pool_8h_html_a3c97656e7bb9d4709eca4ed29abf9d9c"><div class="ttname"><a href="threads__pool_8h.html#a3c97656e7bb9d4709eca4ed29abf9d9c">addThread</a></div><div class="ttdeci">int addThread(ThreadsPoolMsg_st_pt trdsPolMsgStPt)</div><div class="ttdoc">向线程池中添加新线程</div><div class="ttdef"><b>Definition</b> <a href="threads__pool_8c_source.html#l00456">threads_pool.c:456</a></div></div>
</div><!-- fragment --><p> 向线程池中动态添加一个工作线程。</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> <a class="code hl_function" href="threads__pool_8h.html#afbfdf354a44f65186b3dfdd80e566b59">reduceThread</a>(<a class="code hl_struct" href="structthreads_pool_msg.html">ThreadsPoolMsg_st_pt</a> trdsPolMsgStPt)</div>
<div class="ttc" id="athreads__pool_8h_html_afbfdf354a44f65186b3dfdd80e566b59"><div class="ttname"><a href="threads__pool_8h.html#afbfdf354a44f65186b3dfdd80e566b59">reduceThread</a></div><div class="ttdeci">int reduceThread(ThreadsPoolMsg_st_pt trdsPolMsgStPt)</div><div class="ttdoc">从线程池中移除线程</div><div class="ttdef"><b>Definition</b> <a href="threads__pool_8c_source.html#l00486">threads_pool.c:486</a></div></div>
</div><!-- fragment --><p> 从线程池中动态移除一个工作线程。</p>
<div class="fragment"><div class="line"><span class="keywordtype">void</span> <a class="code hl_function" href="threads__pool_8h.html#a9ebf8832444bfb71e5cc1549ec38e354">destroyThreadsPoolMsg</a>(<a class="code hl_struct" href="structthreads_pool_msg.html">ThreadsPoolMsg_st_pt</a> trdsPolMsgStPt)</div>
<div class="ttc" id="athreads__pool_8h_html_a9ebf8832444bfb71e5cc1549ec38e354"><div class="ttname"><a href="threads__pool_8h.html#a9ebf8832444bfb71e5cc1549ec38e354">destroyThreadsPoolMsg</a></div><div class="ttdeci">void destroyThreadsPoolMsg(ThreadsPoolMsg_st_pt trdsPolMsgStPt)</div><div class="ttdoc">销毁线程池</div><div class="ttdef"><b>Definition</b> <a href="threads__pool_8c_source.html#l00556">threads_pool.c:556</a></div></div>
</div><!-- fragment --><p> 安全地销毁线程池，释放所有资源。</p>
<h1><a class="anchor" id="autotoc_md10"></a>
基础用法示例</h1>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;stdio.h&gt;</span></div>
<div class="line"><span class="preprocessor">#include &lt;unistd.h&gt;</span></div>
<div class="line"><span class="preprocessor">#include &quot;<a class="code" href="threads__pool_8h.html">threads_pool.h</a>&quot;</span></div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">void</span>* example_task(<span class="keywordtype">void</span>* arg) {</div>
<div class="line">    <span class="keywordtype">int</span> task_id = *((<span class="keywordtype">int</span>*)arg);</div>
<div class="line">    printf(<span class="stringliteral">&quot;Task %d is starting on thread %lu.\n&quot;</span>, task_id, (<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)pthread_self());</div>
<div class="line">    sleep(1);</div>
<div class="line">    printf(<span class="stringliteral">&quot;Task %d is finished.\n&quot;</span>, task_id);</div>
<div class="line">    <span class="keywordflow">return</span> NULL;</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">int</span> <a class="code hl_function" href="threads__pool__test_8c.html#ae66f6b31b5ad750f1fe042a706a4e3d4">main</a>() {</div>
<div class="line">    <a class="code hl_struct" href="structthreads_pool_msg.html">ThreadsPoolMsg_st_pt</a> pool = <a class="code hl_function" href="threads__pool_8h.html#a871605529dee3dac1537de63589ab108">getNewThreadsPoolMsg</a>(3, 100, 10);</div>
<div class="line">    <span class="keywordflow">if</span> (pool == NULL) <span class="keywordflow">return</span> 1;</div>
<div class="line"> </div>
<div class="line">    <span class="keywordtype">int</span> task_ids[5];</div>
<div class="line">    <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; 5; ++i) {</div>
<div class="line">        task_ids[i] = i + 1;</div>
<div class="line">        <a class="code hl_function" href="threads__pool_8h.html#a3ceec63a2e1c63606f561486b0b24e72">addNewTask</a>(pool, example_task, (<span class="keywordtype">void</span>*)&amp;task_ids[i]);</div>
<div class="line">    }</div>
<div class="line"> </div>
<div class="line">    sleep(2);</div>
<div class="line">    <a class="code hl_function" href="threads__pool_8h.html#a3c97656e7bb9d4709eca4ed29abf9d9c">addThread</a>(pool);</div>
<div class="line"> </div>
<div class="line">    <span class="keywordtype">int</span> more_task_ids[2] = {6, 7};</div>
<div class="line">    <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; 2; ++i) {</div>
<div class="line">        <a class="code hl_function" href="threads__pool_8h.html#a3ceec63a2e1c63606f561486b0b24e72">addNewTask</a>(pool, example_task, (<span class="keywordtype">void</span>*)&amp;more_task_ids[i]);</div>
<div class="line">    }</div>
<div class="line"> </div>
<div class="line">    sleep(3);</div>
<div class="line">    <a class="code hl_function" href="threads__pool_8h.html#a9ebf8832444bfb71e5cc1549ec38e354">destroyThreadsPoolMsg</a>(pool);</div>
<div class="line">    printf(<span class="stringliteral">&quot;Thread pool destroyed.\n&quot;</span>);</div>
<div class="line"> </div>
<div class="line">    <span class="keywordflow">return</span> 0;</div>
<div class="line">}</div>
<div class="ttc" id="athreads__pool_8h_html"><div class="ttname"><a href="threads__pool_8h.html">threads_pool.h</a></div><div class="ttdoc">线程池模块头文件</div></div>
<div class="ttc" id="athreads__pool__test_8c_html_ae66f6b31b5ad750f1fe042a706a4e3d4"><div class="ttname"><a href="threads__pool__test_8c.html#ae66f6b31b5ad750f1fe042a706a4e3d4">main</a></div><div class="ttdeci">int main()</div><div class="ttdef"><b>Definition</b> <a href="threads__pool__test_8c_source.html#l00033">threads_pool_test.c:33</a></div></div>
</div><!-- fragment --><h1><a class="anchor" id="autotoc_md11"></a>
详细配置</h1>
<p>创建线程池时需要指定关键参数：</p><ul>
<li><code>orgActiveThreadsCot</code>: 初始工作线程数量（必须 &gt; 0）</li>
<li><code>maxWaitingTasksCot</code>: 任务队列最大容量</li>
<li><code>maxActiveThreadsCot</code>: 最大工作线程数</li>
</ul>
<h1><a class="anchor" id="autotoc_md12"></a>
注意事项</h1>
<ol type="1">
<li>任务函数必须是线程安全的，接受 <code>void*</code> 参数并返回 <code>void*</code>。</li>
<li>确保任务参数的寿命足够长，建议动态分配或在任务中复制。</li>
<li>调用 <code>destroyThreadsPoolMsg</code> 后切勿再使用该线程池指针。</li>
<li>检查 API 函数的返回值以确保操作成功。</li>
<li>根据硬件性能和工作负载类型合理设置线程数量。</li>
</ol>
<h1><a class="anchor" id="autotoc_md13"></a>
许可证</h1>
<p>本项目基于 MIT License 开源。详情请查看源码文件中的许可证声明。</p>
<h1><a class="anchor" id="autotoc_md14"></a>
作者</h1>
<p>连佳炜 - (2025-09-12) </p>
</div></div><!-- PageDoc -->
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
生成于 2025年 九月 13日 星期六 03:23:00 , 为 线程池使用 &#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.8
</small></address>
</body>
</html>
